package com.muyu.payment.controller;

import java.util.List;


import com.muyu.common.core.web.controller.BaseController;
import com.muyu.common.core.domain.Result;
import com.muyu.common.core.web.page.PageQueryModel;
import com.muyu.common.core.web.page.DataPageResp;
import com.muyu.common.core.utils.poi.ExcelUtil;
import com.muyu.common.security.annotation.RequiresPermissions;
import com.muyu.payment.domain.PaymentRefund;
import com.muyu.payment.domain.model.PaymentRefundQueryModel;
import com.muyu.payment.domain.model.PaymentRefundPageQueryModel;
import com.muyu.payment.domain.model.PaymentRefundSaveModel;
import com.muyu.payment.domain.model.PaymentRefundAuditModel;
import com.muyu.payment.service.PaymentRefundService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 支付退款申请Controller
 *
 * @author muyu
 * @date 2025-09-16
 */
@Tag(name = "支付退款申请管理", description = "支付退款申请相关接口")
@RestController
@RequestMapping("/refund")
public class PaymentRefundController extends BaseController {
    
    @Autowired
    private PaymentRefundService paymentRefundService;

    /**
     * 查询支付退款申请列表
     */
    @Operation(summary = "查询退款申请列表", description = "分页查询退款申请列表")
    @RequiresPermissions("payment:refund:list")
    @GetMapping("/list")
    public Result<DataPageResp<PaymentRefundPageQueryModel>> list(PaymentRefundQueryModel queryModel) {
        PageQueryModel<PaymentRefundPageQueryModel> pageQueryModel = paymentRefundService.pageQuery(queryModel);
        return Result.success(DataPageResp.of(pageQueryModel));
    }

    /**
     * 导出支付退款申请列表
     */
    @Operation(summary = "导出退款申请列表", description = "导出退款申请数据到Excel")
    @RequiresPermissions("payment:refund:export")
    @PostMapping("/export")
    public void export(HttpServletResponse response, PaymentRefund queryModel) {
        List<PaymentRefund> list = paymentRefundService.exportList(queryModel);
        ExcelUtil<PaymentRefund> util = new ExcelUtil<PaymentRefund>(PaymentRefund.class);
        util.exportExcel(response, list, "支付退款申请数据");
    }

    /**
     * 获取支付退款申请详细信息
     */
    @Operation(summary = "获取退款申请详情", description = "根据ID获取退款申请详细信息")
    @RequiresPermissions("payment:refund:getInfo")
    @GetMapping(value = "/{id}")
    public Result getInfo(@PathVariable("id") Long id) {
        return success(paymentRefundService.getById(id));
    }

    /**
     * 新增支付退款申请
     */
    @Operation(summary = "新增退款申请", description = "创建新的退款申请记录")
    @RequiresPermissions("payment:refund:add")
    @PostMapping
    public Result add(@RequestBody PaymentRefundSaveModel saveModel) {
        paymentRefundService.save(saveModel);
        return success();
    }

    /**
     * 用户申请退款
     */
    @Operation(summary = "用户申请退款", description = "用户提交退款申请")
    @RequiresPermissions("payment:refund:applyRefund")
    @PostMapping("/apply")
    public Result applyRefund(@RequestBody PaymentRefundSaveModel saveModel) {
        try {
            String refundNo = paymentRefundService.applyRefund(saveModel);
            return success("退款申请提交成功，申请号：" + refundNo);
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 审核退款申请
     */
    @Operation(summary = "审核退款申请", description = "管理员审核退款申请")
    @RequiresPermissions("payment:refund:auditRefund")
    @PutMapping("/audit")
    public Result auditRefund(@RequestBody PaymentRefundAuditModel auditModel) {
        try {
            paymentRefundService.auditRefund(auditModel);
            return success("审核完成");
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 执行退款
     */
    @Operation(summary = "执行退款", description = "执行退款操作")
    @RequiresPermissions("payment:refund:processRefund")
    @PostMapping("/process/{refundNo}")
    public Result processRefund(@PathVariable("refundNo") String refundNo) {
        try {
            paymentRefundService.processRefund(refundNo);
            return success("退款处理完成");
        } catch (Exception e) {
            return error(e.getMessage());
        }
    }

    /**
     * 根据订单号查询退款申请
     */
    @Operation(summary = "查询订单退款记录", description = "根据订单号查询退款申请记录")
    @RequiresPermissions("payment:refund:getRefundsByOrderNo")
    @GetMapping("/order/{orderNo}")
    public Result getRefundsByOrderNo(@PathVariable("orderNo") String orderNo) {
        List<PaymentRefund> refunds = paymentRefundService.getRefundsByOrderNo(orderNo);
        return success(refunds);
    }

    /**
     * 检查订单是否可以申请退款
     */
    @Operation(summary = "检查退款条件", description = "检查订单是否满足退款条件")
    @RequiresPermissions("payment:refund:canApplyRefund")
    @GetMapping("/check/{orderNo}/{userId}")
    public Result canApplyRefund(@PathVariable("orderNo") String orderNo, @PathVariable("userId") Long userId) {
        boolean canRefund = paymentRefundService.canApplyRefund(orderNo, userId);
        return success(canRefund);
    }

    /**
     * 修改支付退款申请
     */
    @Operation(summary = "修改退款申请", description = "修改退款申请信息")
    @RequiresPermissions("payment:refund:edit")
    @PutMapping
    public Result edit(@RequestBody PaymentRefund paymentRefund) {
        return toAjax(paymentRefundService.updateById(paymentRefund));
    }

    /**
     * 删除支付退款申请
     */
    @Operation(summary = "删除退款申请", description = "删除退款申请记录")
    @RequiresPermissions("payment:refund:remove")
    @DeleteMapping("/{ids}")
    public Result remove(@PathVariable Long[] ids) {
        return toAjax(paymentRefundService.removeByIds(List.of(ids)));
    }
}